<?php

// +----------------------------------------------------------------------
// | ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2022 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: https://thinkadmin.top
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// | 免费声明 ( https://thinkadmin.top/disclaimer )
// +----------------------------------------------------------------------
// | gitee 代码仓库：https://gitee.com/zoujingli/ThinkAdmin
// | github 代码仓库：https://github.com/zoujingli/ThinkAdmin
// +----------------------------------------------------------------------

namespace app\api\controller;

use AliPay\App;
use app\api\model\DaoVipDetail;
use think\admin\Controller;
use think\admin\model\SystemBase;
use think\admin\model\SystemConfig;


/**
 * Class Pay
 * @package app\api\controller\v1
 */
class Pay extends Controller
{

    /**
     * 错误信息状态码描述
     * @var string[]
     */
    protected $err_msg = [
        '21000' => 'App Store不能读取你提供的JSON对象',
        '21002' => 'receipt-data域的数据有问题',
        '21003' => 'receipt无法通过验证',
        '21004' => '提供的shared secret不匹配你账号中的shared secret',
        '21005' => 'receipt服务器当前不可用',
        '21006' => 'receipt合法，但是订阅已过期。服务器接收到这个状态码时，receipt数据仍然会解码并一起发送',
        '21007' => 'receipt是Sandbox receipt，但却发送至生产系统的验证服务',
        '21008' => 'receipt是生产receipt，但却发送至Sandbox环境的验证服务'
    ];

    /**
     * 控制器初始化
     */
    protected function initialize()
    {
        parent::initialize();
        //解决跨域
        $this->corsOptionsHandler();
    }

    public function corsOptionsHandler()
    {
        if (request()->isOptions()) {
            header('Access-Control-Allow-Origin:*');
            header('Access-Control-Allow-Headers:Accept,Referer,Host,Keep-Alive,User-Agent,X-Requested-With,Cache-Control,Content-Type,Cookie,token');
            header('Access-Control-Allow-Credentials:true');
            header('Access-Control-Allow-Methods:GET,POST,OPTIONS');
            header('Access-Control-Max-Age:1728000');
            header('Content-Type:text/plain charset=UTF-8');
            header('Content-Length: 0', true);
            header('status: 204');
            header('HTTP/1.0 204 No Content');
        } else {
            header('Access-Control-Allow-Origin:*');
            header('Access-Control-Allow-Headers:Accept,Referer,Host,Keep-Alive,User-Agent,X-Requested-With,Cache-Control,Content-Type,Cookie,token');
            header('Access-Control-Allow-Credentials:true');
            header('Access-Control-Allow-Methods:GET,POST,OPTIONS');
        }
    }

    /**
     * 获取支付支付数据
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getPayConfig()
    {
        $data = $this->_vali([
            'name.require' => '缺少用户名~',
            'pay_type.require' => '请选择支付方式~',
            'vip_type.require' => '缺少必要参数~'
        ]);
        $config = config('pay');
        $this_vip = [];
        foreach ($config['vip_list'] as $vip) {
            if ($vip['type'] == $data['vip_type']) $this_vip = $vip;
        }
        if (empty($this_vip)) $this->error('会员类型错误，请正确选择~');
        try {
            $pay = App::instance($config['alipay_config']);
            $trade_sn = create_sn();
            $order_info = [
                'user_name' => $data['name'],
                'vip_sn' => $trade_sn,
                'buy_money' => $this_vip['money'],
                'buy_time' => date('Y-m-d H:i:s'),
                'type' => $data['vip_type'],
                'desc' => "支付宝APP支付 {$this_vip['name']}购买",
                'ip' => $this->app->request->ip(),
                'pay_mode' => 2,
                'appid' => $config['alipay_config']['appid'],
            ];
            $bool = DaoVipDetail::mk()->insert($order_info);
            if (!$bool) $this->error('订单生成失败~');
            $result = $pay->apply([
                'out_trade_no' => $trade_sn, // 商户订单号
                'total_amount' => $this_vip['money'],    // 支付金额
                'subject' => "支付宝APP支付 {$this_vip['name']}购买", // 支付订单描述
            ]);
            sysoplog('getPayConfig', json_encode($result));

        } catch (\Exception $e) {
            $this->error('获取失败:' . json_encode($e->getMessage()));
        }
        $this->success('获取成功', $result);
    }

    /**
     * @return void
     * @throws \WeChat\Exceptions\InvalidResponseException
     * @throws \WeChat\Exceptions\LocalCacheException
     */
    function getWxPayConfig()
    {
        $data = $this->_vali([
            'name.require' => '缺少用户名~',
            'pay_type.require' => '请选择支付方式~',
            'vip_type.require' => '缺少必要参数~'
        ]);
        $wx_config = SystemConfig::mk()->where(['type' => 'wechat'])->column('value', 'name');
        $wx_config = [
            'appid' => $wx_config['appid'],
            // 配置商户支付参数（可选，在使用支付功能时需要）
            'mch_id' => $wx_config['mch_id'],
            'mch_v3_key' => $wx_config['mch_v3_key'],
            //'cert_serial' => $wx_config['mch_cert_serial'],
            'cert_private' => syspath($wx_config['mch_ssl_key']),
            // 微信商户证书私钥（必填）：可填写证书内容或文件路径，用于请求数据签名
            'cert_public' => syspath($wx_config['mch_ssl_cer']),
            'cert_package' => [
                'PUB_KEY_ID_0116996292602024112100298900000415' => syspath($wx_config['pub_key'])
            ],
        ];
        // 创建接口实例
        //$wechat = new \WeChat\Pay($wx_config);
        $wechat = \WePayV3\Order::instance($wx_config);
        // 组装参数，可以参考官方商户文档
        $config = config('pay');
        $this_vip = [];
        foreach ($config['vip_list'] as $vip) {
            if ($vip['type'] == $data['vip_type']) $this_vip = $vip;
        }
        if (empty($this_vip)) $this->error('会员类型错误，请正确选择~');
        $trade_sn = create_sn();
        $order_info = [
            'user_name' => $data['name'],
            'vip_sn' => $trade_sn,
            'buy_money' => $this_vip['money'],
            'buy_time' => date('Y-m-d H:i:s'),
            'type' => $data['vip_type'],
            'desc' => "微信APP支付 {$this_vip['name']}购买",
            'ip' => $this->app->request->ip(),
            'pay_mode' => 1,
            'appid' => 'wxcbbd97719f95cc91',
        ];
        $bool = DaoVipDetail::mk()->insert($order_info);
        if (!$bool) $this->error('订单生成失败~');
        $options = [
            'appid' => $wx_config['appid'],
            'mchid' => $wx_config['mch_id'],
            'description' => "微信APP支付 {$this_vip['name']}购买",
            'out_trade_no' => $trade_sn,
            'trade_type' => 'APP',
            'notify_url' => sysuri('api/notify/wxpay', [], false, true),
            'amount' => ['total' => $this_vip['money'] * 100, 'currency' => 'CNY']
        ];
        try {
            // 生成预支付码
            //$result = $wechat->createOrder($options);

            $result = $wechat->create('app', $options);
            // 创建JSAPI参数签名
            //$options = $wechat->createParamsForApp($result['prepay_id']);
            sysoplog('微信支付参数', json_encode($result));
            // @todo 把 $options 传到前端用js发起支付就可以了

        } catch (\Exception $e) {

            // 出错啦，处理下吧
            echo $e->getMessage() . PHP_EOL;

        }
        //$this->success('获取成功', $options);
        $this->success('获取成功', $result);
    }

    function getIosPayConfig()
    {
        $data = $this->_vali([
            'username.require' => '缺少用户名~',
            'productId.require' => '请选择支付方式~'
        ]);
        $config = config('pay');
        $this_vip = [];
        foreach ($config['vip_list'] as $vip) {
            if ($vip['type'] == $data['productId']) $this_vip = $vip;
        }
        if (empty($this_vip)) $this->error('会员类型错误，请正确选择~');
        $trade_sn = create_sn();
        $order_info = [
            'user_name' => $data['username'],
            'vip_sn' => $trade_sn,
            'buy_money' => $this_vip['money'],
            'buy_time' => date('Y-m-d H:i:s'),
            'type' => $data['productId'],
            'desc' => "苹果APP支付 {$this_vip['name']}购买",
            'ip' => $this->app->request->ip(),
            'pay_mode' => 4
        ];
        $bool = DaoVipDetail::mk()->insert($order_info);
        if (!$bool) $this->error('订单生成失败~');
        $this->success('获取成功', ['order_id' => $trade_sn]);
    }

    function getPayInfo()
    {
        $vip_list = config('pay.vip_list');
        $pay_list = SystemBase::mk()->items('支付方式');
        $new_pay_list = [];
        foreach ($pay_list as $key => $value) {
            if (!empty($value['code']) && $value['code'] != 'appleiap' && $value['code'] != 'pc') {
                $new_pay_list[] = [
                    'name' => $value['code'],
                    'text' => $value['name'],
                    'type' => $value['content'],
                    'plain' => true
                ];
            }
        }
        $this->success('获取成功', [
            'pay_list' => $new_pay_list,
            'vip_list' => $vip_list
        ]);
    }
}